home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / appletalk / uab.shar / dlip.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-12  |  6.1 KB  |  277 lines

  1. static char rcsid[] = "$Author: cck $ $Date: 88/09/14 10:19:20 $";
  2. static char rcsident[] = "$Header: /src/local/mac/cap/etalk/RCS/dlip.c,v 1.11 88/09/14 10:19:20 cck Rel $";
  3. static char revision[] = "$Revision: 1.11 $";
  4.  
  5. /*
  6.  * dlip.c - Simple "protocol" level interface to DLI
  7.  *
  8.  *  Provides ability to read/write packets at ethernet level
  9.  *
  10.  * Copyright (c) 1988 by The Trustees of Columbia University 
  11.  *  in the City of New York.
  12.  *
  13.  * Permission is granted to any individual or institution to use,
  14.  * copy, or redistribute this software so long as it is not sold for
  15.  * profit, provided that this notice and the original copyright
  16.  * notices are retained.  Columbia University nor the author make no
  17.  * representations about the suitability of this software for any
  18.  * purpose.  It is provided "as is" without express or implied
  19.  * warranty.
  20.  *
  21.  *
  22.  * Edit History:
  23.  *
  24.  *  April 3, 1988  CCKim Created
  25.  *
  26. */
  27.  
  28. static char columbia_copyright[] = "Copyright (c) 1988 by The Trustees of \
  29. Columbia University in the City of New York";
  30.  
  31. #include <stdio.h>
  32. #include <ctype.h>
  33. #include <sys/types.h>
  34. #include <sys/socket.h>
  35. #include <sys/ioctl.h>
  36. #include <sys/uio.h>
  37.  
  38. #include <net/if.h>
  39. #include <netinet/in.h>
  40. #include <netinet/if_ether.h>
  41. #include <netdnet/dli_var.h>
  42.  
  43. #include <netat/appletalk.h>
  44. #include "proto_intf.h"
  45.  
  46. typedef struct ephandle {    /* ethernet protocol driver handle */
  47.   int inuse;            /* true if inuse */
  48.   int socket;            /* file descriptor of socket */
  49.   int protocol;            /* ethernet protocol */
  50.   struct sockaddr_dl sdli;    /* dli interface: to send with */
  51.   struct sockaddr_dl rdli;    /* dli interface: to receive with */
  52. } EPHANDLE;
  53.  
  54. private inited = FALSE;
  55.  
  56. private EPHANDLE ephlist[MAXOPENPROT];
  57.  
  58. /*
  59.  * setup for particular device devno
  60.  * all pi_open's will go this device
  61.  *
  62. */
  63. export
  64. pi_setup()
  65. {
  66.   int i;
  67.  
  68.   if (!inited) {
  69.     for (i = 0 ; i < MAXOPENPROT; i++)
  70.       ephlist[i].inuse = FALSE;
  71.     (void)init_fdlistening();
  72.     inited = TRUE;        /* don't forget now */
  73.   }
  74. }
  75.  
  76. /*
  77.  * Open up a protocol handle:
  78.  *   user level data:
  79.  *      file descriptor
  80.  *      protocol
  81.  * 
  82.  *   returns -1 and ephandle == NULL if memory allocation problems
  83.  *   returns -1 for other errors
  84.  *   return 0 for okay
  85. */
  86. export int
  87. pi_open(protocol, dev, devno)
  88. int protocol;
  89. char *dev;
  90. int devno;
  91. {
  92.   struct ephandle *eph;
  93.   struct sockaddr_dl *dl;
  94.   int s;
  95.   int i;
  96.  
  97.   for (i = 0; i < MAXOPENPROT; i++) {
  98.     if (!ephlist[i].inuse)
  99.       break;
  100.   }
  101.   if (i == MAXOPENPROT)
  102.     return(0);            /* nothing */
  103.   eph = &ephlist[i];        /* find handle */
  104.  
  105.   dl = &eph->sdli;        /* point */
  106.   dl->dli_family = AF_DLI;
  107.   strcpy(dl->dli_device.dli_devname, dev);
  108.   dl->dli_device.dli_devnumber = devno;
  109.   dl->dli_substructype = DLI_ETHERNET;
  110.   /*  update these */
  111.   dl->choose_addr.dli_eaddr.dli_ioctlflg = DLI_EXCLUSIVE;
  112.   dl->choose_addr.dli_eaddr.dli_protype = protocol;
  113.  
  114.   if ((s = socket(AF_DLI, SOCK_DGRAM, DLPROTO_DLI)) < 0)
  115.     return(-1);
  116.   if (bind(s, dl, sizeof(struct sockaddr_dl)) < 0) {
  117.     close(s);
  118.     return(-1);
  119.   }
  120.   bcopy(dl, &eph->rdli, sizeof(struct sockaddr_dl));
  121.  
  122.   eph->inuse = TRUE;
  123.   eph->socket = s;
  124.   eph->protocol = protocol;
  125.   return(i+1);            /* skip zero */
  126. }
  127.  
  128. /* returns TRUE if machine will see own broadcasts */
  129. export int
  130. pi_delivers_self_broadcasts()
  131. {
  132.   return(TRUE);
  133. }
  134.  
  135. export int
  136. pi_close(edx)
  137. int edx;
  138. {
  139.   if (edx < 1 || edx > MAXOPENPROT || !ephlist[edx-1].inuse)
  140.     return(-1);
  141.   fdunlisten(ephlist[edx-1].socket); /* toss listener */
  142.   close(ephlist[edx-1].socket);
  143.   ephlist[edx-1].inuse = 0;
  144.   return(0);
  145. }
  146.  
  147. export int
  148. pi_get_ethernet_address(edx,ea)
  149. int edx;
  150. u_char *ea;
  151. {
  152.   struct ifdevea buf;
  153.   struct ephandle *eph;
  154.  
  155.   if (edx < 1 || edx > MAXOPENPROT || !ephlist[edx-1].inuse)
  156.     return(-1);
  157.  
  158.   eph = &ephlist[edx-1];        /* find handle */
  159.   sprintf(buf.ifr_name, "%s%d",eph->sdli.dli_device.dli_devname,
  160.       eph->sdli.dli_device.dli_devnumber);
  161.   if (ioctl(eph->socket,SIOCRPHYSADDR, &buf) < 0) {
  162.     perror("iotcl");
  163.     return(-1);
  164.   }
  165.   bcopy(buf.current_pa, ea, DLI_EADDRSIZE);
  166.   return(0);
  167. }
  168.  
  169. export
  170. pi_listener(edx, listener, arg)
  171. int edx;
  172. int (*listener)();
  173. caddr_t arg;
  174. {
  175.   if (edx < 1 || edx > MAXOPENPROT || !ephlist[edx-1].inuse)
  176.     return(-1);
  177.  
  178.   fdlistener(ephlist[edx-1].socket, listener, arg, edx);
  179.   return(0);
  180. }
  181.  
  182.  
  183. export int
  184. pi_readv(edx, iov, iovlen)
  185. int edx;
  186. struct iovec *iov;
  187. int iovlen;
  188. {
  189.   struct msghdr msg;
  190.   int cc;
  191.   struct ephandle *eph ;
  192.   struct ethernet_addresses *ea;
  193.  
  194.   if (edx < 1 || edx > MAXOPENPROT)
  195.     return(-1);
  196.   eph = &ephlist[edx-1];
  197.   if (!eph->inuse)
  198.     return(-1);
  199.  
  200.   msg.msg_iov = iov+1;
  201.   msg.msg_iovlen = iovlen-1;
  202.   msg.msg_name = (caddr_t)&eph->rdli;
  203.   msg.msg_namelen = sizeof(eph->rdli);
  204.   msg.msg_accrights = 0;
  205.   msg.msg_accrightslen = 0;
  206.   if ((cc = recvmsg(eph->socket, &msg, 0)) < 0) {
  207.     perror("recvmsg");
  208.     return(cc);
  209.   }
  210.   ea = (struct ethernet_addresses *)iov[0].iov_base;
  211.   ea->etype = eph->protocol;
  212.   /* check length -- naw */
  213.   bcopy(eph->rdli.choose_addr.dli_eaddr.dli_target, ea->saddr, EHRD);
  214.   bcopy(eph->rdli.choose_addr.dli_eaddr.dli_dest, ea->daddr, EHRD);
  215.   return(cc+iov[0].iov_len);
  216. }
  217.  
  218. export int
  219. pi_read(edx, buf, bufsiz)
  220. int edx;
  221. caddr_t buf;
  222. int bufsiz;
  223. {
  224.   struct iovec iov[2];
  225.   struct ethernet_addresses ea;
  226.   int cc;
  227.  
  228.   iov[0].iov_base = (caddr_t)&ea;
  229.   iov[0].iov_len = sizeof(ea);
  230.   iov[1].iov_base = (caddr_t)buf;
  231.   iov[1].iov_len = bufsiz;
  232.   cc = pi_readv(edx, iov, 2);
  233.   return(cc - sizeof(ea));
  234. }
  235.  
  236. export int
  237. pi_write(edx, buf, buflen, eaddr)
  238. int edx;
  239. caddr_t buf;
  240. int buflen;
  241. char *eaddr;
  242. {
  243.   struct iovec iov[1];
  244.  
  245.   iov[0].iov_base = buf;
  246.   iov[0].iov_len = buflen;
  247.   return(pi_writev(edx, iov, 1, eaddr));
  248. }
  249.  
  250. export int
  251. pi_writev(edx, iov, iovlen, eaddr)
  252. int edx;
  253. struct iovec *iov;
  254. int iovlen;
  255. char *eaddr;
  256. {
  257.   struct ephandle *eph;
  258.   struct msghdr msg;
  259.   int cc;
  260.  
  261.   if (edx < 1 || edx > MAXOPENPROT || eaddr == NULL)
  262.     return(-1);
  263.   eph = &ephlist[edx-1];
  264.   if (!eph->inuse)
  265.     return(-1);
  266.  
  267.   bcopy(eaddr, eph->sdli.choose_addr.dli_eaddr.dli_target, DLI_EADDRSIZE);
  268.   msg.msg_name = (caddr_t)&eph->sdli;
  269.   msg.msg_namelen = sizeof(eph->sdli);
  270.   msg.msg_accrights = 0;
  271.   msg.msg_accrightslen = 0;
  272.   msg.msg_iov = iov;
  273.   msg.msg_iovlen = iovlen;
  274.   cc = sendmsg(eph->socket, &msg, 0);
  275.   return(cc);
  276. }
  277.